package com.a01_2021.thousandstimes.exception;

import com.a01_2021.thousandstimes.utils.AjaxResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MissingRequestHeaderException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.sql.SQLException;


/**
 * @Author E1xP@foxmail.com
 * @Version 1.0
 * @PACKAGE_NAME com.a01_2021.thousandstimes.exception
 * @CLASS_NAME GlobalExceptionHandler
 * @Description TODO 全局异常处理类
 * @Date 2021/2/26 下午 2:02
 **/
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    //Logger
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 用于处理Spel表达式异常
     *
     * @param request 请求
     * @param e       异常
     * @return 返还AjaxResponse
     */
    @ExceptionHandler(value = SpelEvaluationException.class)
    public AjaxResponse spelEvaluationExceptionHandler(HttpServletRequest request, SpelEvaluationException e) {
        logger.warn("SpelEvaluationException:" + e.getMessage() +
                ",From:" + request.getRemoteAddr() +
                ",Path:" + request.getRequestURI());
        e.printStackTrace();
        return AjaxResponse.error(e.getMessage());
    }

    /**
     * 用于处理请求头缺失数据
     *
     * @param request 请求
     * @param e       异常
     * @return 返还AjaxResponse
     */
    @ExceptionHandler(value = MissingRequestHeaderException.class)
    public AjaxResponse missingRequestHeaderExceptionHandler(HttpServletRequest request, MissingRequestHeaderException e) {
        logger.warn("MissingRequestHeaderException:" + e.getMessage() +
                ",From:" + request.getRemoteAddr() +
                ",Path:" + request.getRequestURI());
        e.printStackTrace();
        return AjaxResponse.error(e.getMessage());
    }

    /**
     * 用于处理找不到类异常
     *
     * @param request 请求
     * @param e       异常
     * @return 返还AjaxResponse
     */
    @ExceptionHandler(value = ClassNotFoundException.class)
    public AjaxResponse classNotFoundException(HttpServletRequest request, MissingRequestHeaderException e) {
        logger.warn("ClassNotFoundException:" + e.getMessage() +
                ",From:" + request.getRemoteAddr() +
                ",Path:" + request.getRequestURI());
        e.printStackTrace();
        return AjaxResponse.error(500, e.getMessage());
    }

    /**
     * 用于处理Sql执行异常
     *
     * @param request 请求
     * @param e       异常
     * @return 返还AjaxResponse
     */
    @ExceptionHandler(value = SQLException.class)
    public AjaxResponse sqlException(HttpServletRequest request, SQLException e) {
        logger.warn("SQLException:" + e.getMessage() +
                ",From:" + request.getRemoteAddr() +
                ",Path:" + request.getRequestURI());
        e.printStackTrace();
        return AjaxResponse.error(500, e.getMessage());
    }

    /**
     * 用于处理错误传入参数异常
     *
     * @param request 请求
     * @param e       异常
     * @return 返还AjaxResponse
     */
    @ExceptionHandler(value = IllegalStateException.class)
    public AjaxResponse illegalStateException(HttpServletRequest request, IllegalStateException e) {
        logger.warn("IllegalStateException:" + e.getMessage() +
                ",From:" + request.getRemoteAddr() +
                ",Path:" + request.getRequestURI());
        e.printStackTrace();
        return AjaxResponse.error(400, e.getMessage());
    }

    /**
     * 用于处理IO异常
     *
     * @param request 请求
     * @param e       异常
     * @return AjaxReseponse
     */
    @ExceptionHandler(value = IOException.class)
    public AjaxResponse IOException(HttpServletRequest request, CustomException e) {
        logger.warn("IOException:" + e.getMessage() +
                ",From:" + request.getRemoteAddr() +
                ",Path:" + request.getRequestURI());
        e.printStackTrace();
        return AjaxResponse.error(e);
    }

    /**
     * 用于处理拒绝访问异常
     *
     * @param request 请求
     * @param e       异常
     * @return AjaxResponse
     */
    @ExceptionHandler(value = AccessDeniedException.class)
    public AjaxResponse AccessDeniedException(HttpServletRequest request, AccessDeniedException e) {
        logger.warn("AccessDeniedException:" + e.getMessage() +
                ",From:" + request.getRemoteAddr() +
                ",Path:" + request.getRequestURI());
        e.printStackTrace();
        return AjaxResponse.error(403, "无权访问，请联系系统管理员！");
    }

    /**
     * 用于处理自定义异常
     *
     * @param request 请求
     * @param e       异常
     * @return 返还AjaxResponse
     */
    @ExceptionHandler(value = CustomException.class)
    public AjaxResponse customException(HttpServletRequest request, CustomException e) {
        logger.warn("CustomException:" + e.getMessage() +
                ",From:" + request.getRemoteAddr() +
                ",Path:" + request.getRequestURI());
        e.printStackTrace();
        return AjaxResponse.error(e);
    }
}